defmodule EliPhxPlay.Context.Accounts do
  @moduledoc """
  用户上下文模块
  """

  import Ecto.Query, warn: false
  alias EliPhxPlay.Repo
  alias EliPhxPlay.ChatSchema.Users

  @doc """
  用户注册模块
  """
def register_user(attrs) do
  # 预检查账号是否存在
  with nil <- get_user_by_account(attrs["account"]),
        {:ok, user} <- create_user_with_changeset(attrs) do
    {:ok, user}
  else
    %Users{} -> {:error, :account_already_exists}
    {:error, changeset} -> {:error, changeset}
  end
end

defp create_user_with_changeset(attrs) do
  %Users{}
  |> Users.changeset(attrs)
  |> Repo.insert()
end


  @doc """
  查询指定id用户
  """
  def get_user(id) do
    Repo.get(Users, id)
  end

  @doc """
  用户登录验证

  ## 参数
  - account: 用户账号
  - password: 明文密码

  ## 返回值
  - {:ok, user} 登录成功
  - {:error, :user_not_found} 用户不存在
  - {:error, :invalid_password} 密码错误
  - {:error, :user_suspended} 用户被禁用

  ## 示例
  case Accounts.authenticate_user("testuser", "123456") do
    {:ok, user} -> IO.puts("登录成功")
    {:error, reason} -> IO.puts("登录失败: reason")
  end
  """

  def authenticate_user(account, password) when is_binary(account) and is_binary(password) do
    case get_user_by_account(account) do
      nil ->
        # 用户不存在
        {:error, :user_not_found}

      user ->
        # 用户存在，验证密码
        if Users.valid_password?(user, password) do  # 👈 这里调用你的 valid_password? 函数
          #  密码正确，检查用户状态
          if user.status == "active" do
            # 用户状态正常，返回用户信息
            {:ok, user}
          else
            # 用户被禁用
            {:error, :user_suspended}
          end
        else
          # 密码错误
          {:error, :invalid_password}
        end
    end
  end


  @doc """
  获取用户信息
  """
  def get_user_by_account(account) do
    Repo.get_by(Users, account: account)
  end


  @doc """
  模糊查询用户昵称和账号限制搜索结果数量为5个
  """
def search_users(query) do
  search_pattern = "%#{String.downcase(query)}%"
  exact_query = String.downcase(query)

  # 如果查询以@开头，生成不带@的版本
  {additional_pattern, additional_exact} = if String.starts_with?(query, "@") do
    cleaned_query = String.replace_leading(query, "@", "")
    cleaned_pattern = "%#{String.downcase(cleaned_query)}%"
    cleaned_exact = String.downcase(cleaned_query)
    {cleaned_pattern, cleaned_exact}
  else
    {nil, nil}
  end

  # 构建查询条件
  base_condition = dynamic([u], ilike(u.account, ^search_pattern) or ilike(u.nickname, ^search_pattern))

  final_condition = if additional_pattern do
    dynamic([u], ^base_condition or ilike(u.account, ^additional_pattern) or ilike(u.nickname, ^additional_pattern))
  else
    base_condition
  end

  from(u in Users,
    where: ^final_condition,
    order_by: [
      # 优先级1: 账号完全匹配 (包括去掉@的版本)
      desc: fragment("CASE WHEN lower(?) = ? OR lower(?) = ? THEN 3 ELSE 0 END",
        u.account, ^exact_query, u.account, ^(additional_exact || "")),
      # 优先级2: 账号部分匹配
      desc: fragment("CASE WHEN lower(?) LIKE ? OR lower(?) LIKE ? THEN 2 ELSE 0 END",
        u.account, ^search_pattern, u.account, ^(additional_pattern || "")),
      # 优先级3: 昵称匹配
      desc: fragment("CASE WHEN lower(?) LIKE ? OR lower(?) LIKE ? THEN 1 ELSE 0 END",
        u.nickname, ^search_pattern, u.nickname, ^(additional_pattern || "")),
      # 最后按账号字母顺序排序
      asc: u.account
    ],
    limit: 5
  )
  |> Repo.all()
  |> Enum.reverse()
end




  @doc """
  根据user_id列表批量获取用户账号、昵称和头像
  """
  def get_users_by_ids(user_ids) do
    from(u in Users,
      where: u.user_id in ^user_ids,
      select: %{
        user_id: u.user_id,
        account: u.account,
        nickname: u.nickname,
        avatar_url: u.avatar_url
      }
    )
    |> Repo.all()
  end




end
